﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;

namespace FranceTriple.Dal
{
    public struct RightLevel
    {
        public static readonly int Reader = 1;
        public static readonly int Author = 2;
        public static readonly int Moderator = 3;
    }

    public class UserAccessDal
    {
        /// <summary>
        /// List des Categories autorisées pour l'utilisateur courant
        /// </summary>
        public static List<ForumCategory> GetForumCategoryAllowedLookup(String AnonymousID)
        {

            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {
                // cas des administrateurs : accès total
                if (Roles.IsUserInRole("RoleAdminForum"))
                    return (from c in ctx.ForumCategorySet
                            orderby c.LabelForumCategory
                            select c).ToList();
                else // cas des utilisateurs authentifiés et des utilisateurs anonymes
                {
                    String[] UserRoles;

                    if (AnonymousID == String.Empty)
                        UserRoles = Roles.GetRolesForUser();
                    else
                        UserRoles = Roles.GetRolesForUser(AnonymousID);

                    var ForumIdAllowed =  (from r in ctx.aspnet_Roles
                            from rf in r.aspnet_RolesForumSet
                            where r.RoleId == rf.Role_Id
                            & UserRoles.Contains(r.RoleName)
                            select rf.Forum_Id).ToList();

                    return (from c in ctx.ForumCategorySet.Include("Forum")
                            where ForumIdAllowed.Contains(c.Forum.Id)
                            orderby c.LabelForumCategory
                            select c).ToList();
                }
            }
        }
        /// <summary>
        /// List des ForumId autorisés pour l'utilisateur courant
        /// </summary>
        public static List<Int32> ForumIdAllowed(String AnonymousID)
        {

            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {
                // cas des administrateurs : accès total
                if (Roles.IsUserInRole("RoleAdminForum"))
                    return (from f in ctx.ForumSet
                            orderby f.OrderForum
                            select f.Id).ToList();
                else // cas des utilisateurs authentifiés et des utilisateurs anonymes
                {
                    String[] UserRoles;

                    if (AnonymousID == String.Empty)
                        UserRoles = Roles.GetRolesForUser();
                    else
                        UserRoles = Roles.GetRolesForUser(AnonymousID);

                    return (from r in ctx.aspnet_Roles
                            from rf in r.aspnet_RolesForumSet
                            where r.RoleId == rf.Role_Id
                            & UserRoles.Contains(r.RoleName)
                            select rf.Forum_Id).ToList();
                }
            }
        }

        /// <summary>
        /// Niveau d'autorisation pour un utilisateur sur un forum
        /// 1 : Lecture
        /// 2 : Auteur
        /// 3 : Modérateur
        /// </summary>
        /// <param name="ForumId"></param>
        /// <returns></returns>
        public static Int32 UserRightLevel(Int32 CategoryId, String AnonymousID)
        {
            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {
                Int32 ForumId = (from c in ctx.ForumCategorySet.Include("Forum")
                                 where c.Id == CategoryId
                                 select c.Forum.Id).First();

                // cas des administrateurs : accès total
                if (Roles.IsUserInRole("RoleAdminForum"))
                    return RightLevel.Moderator;
                else // cas des utilisateurs authentifiés et des utilisateurs anonymes
                {
                    String[] UserRoles;

                    if (AnonymousID == String.Empty)
                        UserRoles = Roles.GetRolesForUser();
                    else
                        UserRoles = Roles.GetRolesForUser(AnonymousID);

                    return (from r in ctx.aspnet_Roles
                            from rf in r.aspnet_RolesForumSet
                            where r.RoleId == rf.Role_Id
                            & rf.Forum_Id == ForumId
                            & UserRoles.Contains(r.RoleName)
                            select rf.RightLevel).DefaultIfEmpty().Max();
                }

            }
        }

        public static Int32 ForumRightLevel(Int32 ForumId, Guid RoleId)
        {
            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {
                return (from rf in ctx.aspnet_RolesForumSet
                        where rf.Forum_Id == ForumId && rf.Role_Id == RoleId
                        select rf.RightLevel).FirstOrDefault();
            }
        }

        public static string GetModerators(Int32 ForumCategoryId)
        {
            StringBuilder sb = new StringBuilder();
            Int32 forumId = ForumDal.GetForumIdByCategoryId(ForumCategoryId);

            using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
            {
                // Modérateurs union Adminstrateurs
                var RolesModeratorAndAdminForumGuidForThisCategory = (from rf in ctx.aspnet_RolesForumSet
                            where (rf.RightLevel == 3) && (rf.Forum_Id==forumId)
                            select rf.Role_Id).Union(
                            from r in ctx.aspnet_Roles
                                          where r.LoweredRoleName == "roleadminforum"
                                          select r.RoleId);

                var RolesModeratorAndAdminForumNameForThisCategory =
                    (from r in ctx.aspnet_Roles
                     where RolesModeratorAndAdminForumGuidForThisCategory.Contains(r.RoleId)
                     select r.RoleName).ToArray();
                foreach (var onerole in RolesModeratorAndAdminForumNameForThisCategory)
                    if (onerole.ToLower() != "public")
                        sb.Append(String.Join(", ",Roles.GetUsersInRole(onerole)));
                    else
                        sb.Append("Public, ");
            }
            return sb.ToString();
        }
    }
}
